# Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
# SPDX-License-Identifier: MIT

"""
数据源管理API路由
提供数据源的CRUD操作和连接测试功能
"""

import logging
from typing import List, Optional, Dict, Any
from fastapi import APIRouter, HTTPException, Depends, Body, Query
from pydantic import BaseModel, Field

from src.database.models import DataSource
from src.server.services.metadata_service import MetadataService
from ..auth_middleware import GetCurrentUser, GetCurrentAdminUser

logger = logging.getLogger(__name__)

router = APIRouter(
    prefix="/api/datasources",
    tags=["数据源管理"],
    responses={404: {"detail": "找不到资源"}},
)

# 数据源创建请求模型
class DataSourceCreate(BaseModel):
    name: str = Field(..., description="数据源名称")
    description: str = Field("", description="数据源描述")
    type: str = Field(..., description="数据源类型，如 'mysql' 或 'oracle'")
    host: str = Field(..., description="主机名或IP地址")
    port: int = Field(..., description="端口号")
    username: str = Field(..., description="用户名")
    password: str = Field(..., description="密码")
    database_name: str = Field(..., description="数据库名")
    schema_name: Optional[str] = Field(None, description="模式名，主要用于Oracle")
    service_name: Optional[str] = Field(None, description="服务名，主要用于Oracle")
    ssl: bool = Field(False, description="是否使用SSL连接")
    ssl_ca: Optional[str] = Field(None, description="SSL CA证书")
    ssl_cert: Optional[str] = Field(None, description="SSL客户端证书")
    ssl_key: Optional[str] = Field(None, description="SSL客户端密钥")

# 数据源更新请求模型
class DataSourceUpdate(BaseModel):
    name: Optional[str] = Field(None, description="数据源名称")
    description: Optional[str] = Field(None, description="数据源描述")
    host: Optional[str] = Field(None, description="主机名或IP地址")
    port: Optional[int] = Field(None, description="端口号")
    username: Optional[str] = Field(None, description="用户名")
    password: Optional[str] = Field(None, description="密码")
    database_name: Optional[str] = Field(None, description="数据库名")
    schema_name: Optional[str] = Field(None, description="模式名，主要用于Oracle")
    service_name: Optional[str] = Field(None, description="服务名，主要用于Oracle")
    ssl: Optional[bool] = Field(None, description="是否使用SSL连接")
    ssl_ca: Optional[str] = Field(None, description="SSL CA证书")
    ssl_cert: Optional[str] = Field(None, description="SSL客户端证书")
    ssl_key: Optional[str] = Field(None, description="SSL客户端密钥")

# 数据源响应模型
class DataSourceResponse(BaseModel):
    id: str = Field(..., description="数据源ID")
    name: str = Field(..., description="数据源名称")
    description: str = Field("", description="数据源描述")
    type: str = Field(..., description="数据源类型")
    host: str = Field(..., description="主机名或IP地址")
    port: int = Field(..., description="端口号")
    username: str = Field(..., description="用户名")
    database_name: str = Field(..., description="数据库名")
    schema_name: Optional[str] = Field(None, description="模式名")
    service_name: Optional[str] = Field(None, description="服务名")
    ssl: bool = Field(False, description="是否使用SSL")
    status: str = Field(..., description="连接状态")
    created_at: str = Field(..., description="创建时间")
    updated_at: str = Field(..., description="更新时间")
    last_connected_at: Optional[str] = Field(None, description="最后连接时间")
    error_message: Optional[str] = Field(None, description="错误信息")
    
    class Config:
        json_schema_extra = {
            "example": {
                "id": "f8c3de3d-1fea-4d7c-a8b0-29f63c4c3454",
                "name": "生产环境MySQL",
                "description": "生产环境主数据库",
                "type": "mysql",
                "host": "localhost",
                "port": 3306,
                "username": "root",
                "database_name": "production",
                "schema_name": None,
                "service_name": None,
                "ssl": False,
                "status": "active",
                "created_at": "2023-01-01T00:00:00",
                "updated_at": "2023-01-01T00:00:00",
                "last_connected_at": "2023-01-01T00:00:00",
                "error_message": None
            }
        }

# 数据源测试连接响应模型
class ConnectionTestResponse(BaseModel):
    success: bool = Field(..., description="连接是否成功")
    message: str = Field(..., description="连接结果消息")
    details: Dict[str, Any] = Field(default_factory=dict, description="详细信息")

# 元数据相关模型
class MetadataResponse(BaseModel):
    success: bool = Field(..., description="操作是否成功")
    data: Optional[Dict[str, Any]] = Field(None, description="元数据内容")
    sync_time: Optional[str] = Field(None, description="同步时间")
    version: Optional[str] = Field(None, description="版本号")
    message: str = Field(..., description="响应消息")

# 向量化相关模型
class VectorizeRequest(BaseModel):
    include_tables: bool = Field(True, description="是否包含表信息")
    include_relationships: bool = Field(True, description="是否包含关系信息")
    include_indexes: bool = Field(False, description="是否包含索引信息")
    include_constraints: bool = Field(False, description="是否包含约束信息")
    enhance_descriptions: bool = Field(True, description="是否增强表描述信息")

class VectorizeResponse(BaseModel):
    success: bool = Field(..., description="操作是否成功")
    vectors_count: int = Field(..., description="生成的向量数量")
    collection_name: str = Field(..., description="Milvus集合名称")
    processing_time: float = Field(..., description="处理时间（秒）")
    message: str = Field(..., description="响应消息")

class VectorizeStatusResponse(BaseModel):
    success: bool = Field(..., description="操作是否成功")
    status: str = Field(..., description="向量化状态: idle, processing, completed, error")
    progress: float = Field(0.0, description="进度百分比 0-100")
    vectors_count: int = Field(0, description="已生成向量数量")
    total_items: int = Field(0, description="总处理项目数")
    started_at: Optional[str] = Field(None, description="开始时间")
    completed_at: Optional[str] = Field(None, description="完成时间")
    error_message: Optional[str] = Field(None, description="错误信息")
    message: str = Field(..., description="响应消息")

class MetadataSearchRequest(BaseModel):
    query: str = Field(..., description="搜索查询")
    datasource_ids: Optional[List[str]] = Field(None, description="数据源ID列表，为空则搜索所有")
    limit: int = Field(10, ge=1, le=100, description="返回结果数量")
    use_smart_search: bool = Field(True, description="是否使用智能多表检索")
    filter_business_domain: Optional[str] = Field(None, description="按业务领域筛选")

class MetadataSearchResponse(BaseModel):
    success: bool = Field(..., description="操作是否成功")
    query: str = Field(..., description="搜索查询")
    results: List[Dict[str, Any]] = Field(..., description="搜索结果")
    count: int = Field(..., description="结果数量")
    message: str = Field(..., description="响应消息")


@router.post("", response_model=DataSourceResponse, status_code=201)
async def create_datasource(
    data: DataSourceCreate,
    user=Depends(GetCurrentAdminUser)
):
    """创建新数据源"""
    try:
        datasource = DataSource.Create(
            name=data.name,
            description=data.description,
            type=data.type,
            host=data.host,
            port=data.port,
            username=data.username,
            password=data.password,
            database=data.database_name,
            schema=data.schema_name,
            service_name=data.service_name,
            ssl=data.ssl,
            ssl_ca=data.ssl_ca,
            ssl_cert=data.ssl_cert,
            ssl_key=data.ssl_key
        )
        
        return {
            "id": datasource.id,
            "name": datasource.name,
            "description": datasource.description,
            "type": datasource.type,
            "host": datasource.host,
            "port": datasource.port,
            "username": datasource.username,
            "database_name": datasource.database,
            "schema_name": datasource.schema,
            "service_name": datasource.service_name,
            "ssl": datasource.ssl,
            "status": datasource.status,
            "created_at": str(datasource.created_at) if datasource.created_at else "",
            "updated_at": str(datasource.updated_at) if datasource.updated_at else "",
            "last_connected_at": str(datasource.last_connected_at) if datasource.last_connected_at else None,
            "error_message": datasource.error_message
        }
    except Exception as e:
        logger.exception(f"创建数据源失败: {e}")
        raise HTTPException(status_code=500, detail=f"创建数据源失败: {str(e)}")


@router.get("", response_model=List[DataSourceResponse])
async def get_all_datasources(
    user=Depends(GetCurrentUser)
):
    """获取所有数据源"""
    try:
        datasources = DataSource.GetAll()
        
        return [{
            "id": ds.id,
            "name": ds.name,
            "description": ds.description,
            "type": ds.type,
            "host": ds.host,
            "port": ds.port,
            "username": ds.username,
            "database_name": ds.database,
            "schema_name": ds.schema,
            "service_name": ds.service_name,
            "ssl": ds.ssl,
            "status": ds.status,
            "created_at": str(ds.created_at) if ds.created_at else "",
            "updated_at": str(ds.updated_at) if ds.updated_at else "",
            "last_connected_at": str(ds.last_connected_at) if ds.last_connected_at else None,
            "error_message": ds.error_message
        } for ds in datasources]
    except Exception as e:
        logger.exception(f"获取数据源列表失败: {e}")
        raise HTTPException(status_code=500, detail=f"获取数据源列表失败: {str(e)}")


@router.get("/{datasource_id}", response_model=DataSourceResponse)
async def get_datasource(
    datasource_id: str,
    user=Depends(GetCurrentUser)
):
    """根据ID获取指定数据源的详细信息"""
    try:
        datasource = DataSource.GetById(datasource_id)
        
        if not datasource:
            raise HTTPException(status_code=404, detail=f"未找到ID为 {datasource_id} 的数据源")
        
        return {
            "id": datasource.id,
            "name": datasource.name,
            "description": datasource.description,
            "type": datasource.type,
            "host": datasource.host,
            "port": datasource.port,
            "username": datasource.username,
            "database_name": datasource.database,
            "schema_name": datasource.schema,
            "service_name": datasource.service_name,
            "ssl": datasource.ssl,
            "status": datasource.status,
            "created_at": str(datasource.created_at) if datasource.created_at else "",
            "updated_at": str(datasource.updated_at) if datasource.updated_at else "",
            "last_connected_at": str(datasource.last_connected_at) if datasource.last_connected_at else None,
            "error_message": datasource.error_message
        }
    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"获取数据源信息失败: {e}")
        raise HTTPException(status_code=500, detail=f"获取数据源信息失败: {str(e)}")


@router.put("/{datasource_id}", response_model=DataSourceResponse)
async def update_datasource(
    datasource_id: str,
    data: DataSourceUpdate,
    user=Depends(GetCurrentAdminUser)
):
    """更新数据源信息"""
    try:
        datasource = DataSource.GetById(datasource_id)
        
        if not datasource:
            raise HTTPException(status_code=404, detail=f"未找到ID为 {datasource_id} 的数据源")
        
        # 更新字段
        if data.name is not None:
            datasource.name = data.name
        if data.description is not None:
            datasource.description = data.description
        if data.host is not None:
            datasource.host = data.host
        if data.port is not None:
            datasource.port = data.port
        if data.username is not None:
            datasource.username = data.username
        if data.password is not None:
            datasource.password = data.password
        if data.database_name is not None:
            datasource.database = data.database_name
        if data.schema_name is not None:
            datasource.schema = data.schema_name
        if data.service_name is not None:
            datasource.service_name = data.service_name
        if data.ssl is not None:
            datasource.ssl = data.ssl
        if data.ssl_ca is not None:
            datasource.ssl_ca = data.ssl_ca
        if data.ssl_cert is not None:
            datasource.ssl_cert = data.ssl_cert
        if data.ssl_key is not None:
            datasource.ssl_key = data.ssl_key
        
        # 数据源信息变更后，设置状态为未连接
        if (data.host or data.port or data.username or data.password or 
            data.database_name or data.schema_name or data.service_name or 
            data.ssl is not None or data.ssl_ca or data.ssl_cert or data.ssl_key):
            datasource.status = 'inactive'
        
        # 保存更改
        success = datasource.Update()
        
        if not success:
            raise HTTPException(status_code=500, detail="更新数据源信息失败")
        
        return {
            "id": datasource.id,
            "name": datasource.name,
            "description": datasource.description,
            "type": datasource.type,
            "host": datasource.host,
            "port": datasource.port,
            "username": datasource.username,
            "database_name": datasource.database,
            "schema_name": datasource.schema,
            "service_name": datasource.service_name,
            "ssl": datasource.ssl,
            "status": datasource.status,
            "created_at": str(datasource.created_at) if datasource.created_at else "",
            "updated_at": str(datasource.updated_at) if datasource.updated_at else "",
            "last_connected_at": str(datasource.last_connected_at) if datasource.last_connected_at else None,
            "error_message": datasource.error_message
        }
    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"更新数据源信息失败: {e}")
        raise HTTPException(status_code=500, detail=f"更新数据源信息失败: {str(e)}")


@router.delete("/{datasource_id}", status_code=204)
async def delete_datasource(
    datasource_id: str,
    user=Depends(GetCurrentAdminUser)
):
    """删除数据源"""
    try:
        datasource = DataSource.GetById(datasource_id)
        
        if not datasource:
            raise HTTPException(status_code=404, detail=f"未找到ID为 {datasource_id} 的数据源")
        
        success = datasource.Delete()
        
        if not success:
            raise HTTPException(status_code=500, detail="删除数据源失败")
    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"删除数据源失败: {e}")
        raise HTTPException(status_code=500, detail=f"删除数据源失败: {str(e)}")


@router.post("/{datasource_id}/test", response_model=ConnectionTestResponse)
async def test_connection(
    datasource_id: str,
    user=Depends(GetCurrentUser)
):
    """测试指定数据源的连接"""
    try:
        datasource = DataSource.GetById(datasource_id)
        
        if not datasource:
            raise HTTPException(status_code=404, detail=f"未找到ID为 {datasource_id} 的数据源")
        
        result = datasource.TestConnection()
        return result
    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"测试数据源连接失败: {e}")
        raise HTTPException(status_code=500, detail=f"测试数据源连接失败: {str(e)}")


@router.post("/test-connection", response_model=ConnectionTestResponse)
async def test_connection_params(
    data: DataSourceCreate = Body(...),
    user=Depends(GetCurrentUser)
):
    """使用提供的参数测试数据库连接(不保存)"""
    try:
        # 创建临时数据源对象
        datasource = DataSource(
            name=data.name,
            description=data.description,
            type=data.type,
            host=data.host,
            port=data.port,
            username=data.username,
            password=data.password,
            database=data.database_name,
            schema=data.schema_name,
            service_name=data.service_name,
            ssl=data.ssl,
            ssl_ca=data.ssl_ca,
            ssl_cert=data.ssl_cert,
            ssl_key=data.ssl_key
        )
        
        # 测试连接但不保存状态
        result = datasource.TestConnection()
        return result
    except Exception as e:
        logger.exception(f"测试数据源连接失败: {e}")
        return {
            "success": False,
            "message": f"连接失败: {str(e)}",
            "details": {}
        }


@router.get("/{datasource_id}/tables")
async def get_tables(
    datasource_id: str,
    user=Depends(GetCurrentUser)
):
    """获取数据源中的表列表"""
    try:
        datasource = DataSource.GetById(datasource_id)
        
        if not datasource:
            raise HTTPException(status_code=404, detail=f"未找到ID为 {datasource_id} 的数据源")
        
        # 测试连接并获取表列表
        if datasource.type == 'mysql':
            import pymysql
            connection = pymysql.connect(
                host=datasource.host,
                port=datasource.port,
                user=datasource.username,
                password=datasource.password,
                database=datasource.database,
                charset='utf8mb4'
            )
            
            with connection.cursor() as cursor:
                # 获取表名和注释
                cursor.execute("""
                    SELECT TABLE_NAME, TABLE_COMMENT
                    FROM INFORMATION_SCHEMA.TABLES 
                    WHERE TABLE_SCHEMA = %s 
                    AND TABLE_TYPE = 'BASE TABLE'
                    ORDER BY TABLE_NAME
                """, (datasource.database,))
                
                tables = []
                for row in cursor.fetchall():
                    table_name, table_comment = row
                    tables.append({
                        "name": table_name,
                        "description": table_comment if table_comment else f"{table_name} 数据表"
                    })
            
            connection.close()
            
            return {
                "success": True,
                "tables": tables,
                "count": len(tables)
            }
            
        elif datasource.type == 'oracle':
            try:
                import cx_Oracle
            except ImportError:
                return {
                    "success": False,
                    "message": "未安装cx_Oracle驱动程序",
                    "tables": []
                }
            
            # 构建DSN
            if datasource.service_name:
                dsn = cx_Oracle.makedsn(datasource.host, datasource.port, service_name=datasource.service_name)
            else:
                dsn = cx_Oracle.makedsn(datasource.host, datasource.port, sid=datasource.database)
            
            connection = cx_Oracle.connect(
                user=datasource.username,
                password=datasource.password,
                dsn=dsn
            )
            
            with connection.cursor() as cursor:
                schema = datasource.schema or datasource.username.upper()
                # 获取表名和注释
                cursor.execute(f"""
                    SELECT t.TABLE_NAME, NVL(c.COMMENTS, t.TABLE_NAME || ' 数据表') as DESCRIPTION
                    FROM ALL_TABLES t
                    LEFT JOIN ALL_TAB_COMMENTS c ON t.OWNER = c.OWNER AND t.TABLE_NAME = c.TABLE_NAME
                    WHERE t.OWNER = '{schema}'
                    ORDER BY t.TABLE_NAME
                """)
                
                tables = []
                for row in cursor.fetchall():
                    table_name, description = row
                    tables.append({
                        "name": table_name,
                        "description": description
                    })
            
            connection.close()
            
            return {
                "success": True,
                "tables": tables,
                "count": len(tables),
                "schema": schema
            }
        
        else:
            return {
                "success": False,
                "message": f"不支持的数据源类型: {datasource.type}",
                "tables": []
            }
    
    except Exception as e:
        logger.exception(f"获取表列表失败: {e}")
        return {
            "success": False, 
            "message": f"获取表列表失败: {str(e)}",
            "tables": []
        }


@router.get("/{datasource_id}/tables/{table_name}/columns")
async def get_table_columns(
    datasource_id: str,
    table_name: str,
    user=Depends(GetCurrentUser)
):
    """获取指定表的列信息"""
    try:
        datasource = DataSource.GetById(datasource_id)
        
        if not datasource:
            raise HTTPException(status_code=404, detail=f"未找到ID为 {datasource_id} 的数据源")
        
        if datasource.type == 'mysql':
            import pymysql
            connection = pymysql.connect(
                host=datasource.host,
                port=datasource.port,
                user=datasource.username,
                password=datasource.password,
                database=datasource.database,
                charset='utf8mb4'
            )
            
            with connection.cursor() as cursor:
                # 清理table_name中可能存在的引号
                clean_table_name = table_name.strip().strip("'\"")
                cursor.execute(f"DESCRIBE {clean_table_name}")
                columns = []
                for row in cursor.fetchall():
                    columns.append({
                        "name": row[0],
                        "type": row[1],
                        "null": row[2] == "YES",
                        "key": row[3],
                        "default": row[4],
                        "extra": row[5]
                    })
            
            connection.close()
            
            return {
                "success": True,
                "table_name": table_name,
                "columns": columns,
                "count": len(columns)
            }
            
        elif datasource.type == 'oracle':
            try:
                import cx_Oracle
            except ImportError:
                return {
                    "success": False,
                    "message": "未安装cx_Oracle驱动程序",
                    "columns": []
                }
            
            # 构建DSN
            if datasource.service_name:
                dsn = cx_Oracle.makedsn(datasource.host, datasource.port, service_name=datasource.service_name)
            else:
                dsn = cx_Oracle.makedsn(datasource.host, datasource.port, sid=datasource.database)
            
            connection = cx_Oracle.connect(
                user=datasource.username,
                password=datasource.password,
                dsn=dsn
            )
            
            with connection.cursor() as cursor:
                schema = datasource.schema or datasource.username.upper()
                # 清理table_name中可能存在的引号
                clean_table_name = table_name.strip().strip("'\"").upper()
                sql = f"""
                SELECT COLUMN_NAME, DATA_TYPE, NULLABLE, DATA_LENGTH, DATA_PRECISION, DATA_SCALE
                FROM ALL_TAB_COLUMNS 
                WHERE OWNER = '{schema}' AND TABLE_NAME = '{clean_table_name}'
                ORDER BY COLUMN_ID
                """
                cursor.execute(sql)
                columns = []
                for row in cursor.fetchall():
                    columns.append({
                        "name": row[0],
                        "type": row[1],
                        "null": row[2] == "Y",
                        "length": row[3],
                        "precision": row[4],
                        "scale": row[5]
                    })
            
            connection.close()
            
            return {
                "success": True,
                "table_name": table_name,
                "columns": columns,
                "count": len(columns),
                "schema": schema
            }
        
        else:
            return {
                "success": False,
                "message": f"不支持的数据源类型: {datasource.type}",
                "columns": []
            }
    
    except Exception as e:
        logger.exception(f"获取表列信息失败: {e}")
        return {
            "success": False,
            "message": f"获取表列信息失败: {str(e)}",
            "columns": []
        }


# ==================== 元数据管理API ====================

@router.get("/{datasource_id}/metadata", response_model=MetadataResponse)
async def get_metadata(
    datasource_id: str,
    use_cache: bool = Query(False, description="是否使用缓存数据，默认False（实时查询）"),
    user=Depends(GetCurrentUser)
):
    """
    获取数据源元数据
    
    Args:
        datasource_id: 数据源ID
        use_cache: 是否使用缓存数据，默认False（实时查询）
            - True: 从本地缓存表读取，速度快但可能不是最新数据
            - False: 直接从数据源实时查询，数据最新但速度较慢
    """
    try:
        datasource = DataSource.GetById(datasource_id)
        if not datasource:
            raise HTTPException(status_code=404, detail=f"未找到ID为 {datasource_id} 的数据源")
        
        logger.info(f"获取数据源 {datasource_id} 元数据，使用缓存: {use_cache}")
        result = MetadataService.get_database_metadata(datasource_id, use_cache=use_cache)
        return result
    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"获取元数据失败: {e}")
        raise HTTPException(status_code=500, detail=f"获取元数据失败: {str(e)}")


@router.get("/{datasource_id}/metadata/realtime", response_model=MetadataResponse)
async def get_metadata_realtime(
    datasource_id: str,
    user=Depends(GetCurrentUser)
):
    """
    实时获取数据源元数据（强制从数据源查询）
    
    这个端点总是从数据源实时查询最新的元数据信息，不使用缓存。
    适用于需要确保数据最新的场景。
    """
    try:
        datasource = DataSource.GetById(datasource_id)
        if not datasource:
            raise HTTPException(status_code=404, detail=f"未找到ID为 {datasource_id} 的数据源")
        
        logger.info(f"强制实时获取数据源 {datasource_id} 元数据")
        result = MetadataService.get_database_metadata(datasource_id, use_cache=False)
        return result
    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"实时获取元数据失败: {e}")
        raise HTTPException(status_code=500, detail=f"实时获取元数据失败: {str(e)}")


# 已弃用的缓存功能已删除


# 已弃用的同步功能已删除





# 已弃用的停止同步功能已删除


# 元数据向量化相关API（基于现有Milvus集成）
@router.post("/{datasource_id}/metadata/vectorize", response_model=VectorizeResponse)
async def vectorize_metadata(
    datasource_id: str,
    request: VectorizeRequest,
    user=Depends(GetCurrentUser)
):
    """向量化数据源元数据"""
    try:
        datasource = DataSource.GetById(datasource_id)
        if not datasource:
            raise HTTPException(status_code=404, detail=f"未找到ID为 {datasource_id} 的数据源")
        
        # 导入向量化服务
        from src.server.services.metadata_vectorize_service import MetadataVectorizeService
        
        # 开始向量化处理
        result = await MetadataVectorizeService.vectorize_datasource_metadata(
            datasource_id=datasource_id,
            include_tables=request.include_tables,
            include_relationships=request.include_relationships,
            include_indexes=request.include_indexes,
            include_constraints=request.include_constraints,
            enhance_descriptions=request.enhance_descriptions
        )
        
        return result
    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"向量化元数据失败: {e}")
        raise HTTPException(status_code=500, detail=f"向量化元数据失败: {str(e)}")


@router.get("/{datasource_id}/metadata/vectorize/status", response_model=VectorizeStatusResponse)
async def get_vectorize_status(
    datasource_id: str,
    user=Depends(GetCurrentUser)
):
    """获取元数据向量化状态"""
    try:
        datasource = DataSource.GetById(datasource_id)
        if not datasource:
            raise HTTPException(status_code=404, detail=f"未找到ID为 {datasource_id} 的数据源")
        
        from src.server.services.metadata_vectorize_service import MetadataVectorizeService
        
        result = MetadataVectorizeService.get_vectorize_status(datasource_id)
        return result
    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"获取向量化状态失败: {e}")
        raise HTTPException(status_code=500, detail=f"获取向量化状态失败: {str(e)}")


@router.delete("/{datasource_id}/metadata/vectors")
async def delete_metadata_vectors(
    datasource_id: str,
    user=Depends(GetCurrentAdminUser)
):
    """删除数据源的元数据向量"""
    try:
        datasource = DataSource.GetById(datasource_id)
        if not datasource:
            raise HTTPException(status_code=404, detail=f"未找到ID为 {datasource_id} 的数据源")
        
        from src.server.services.metadata_vectorize_service import MetadataVectorizeService
        
        result = await MetadataVectorizeService.delete_datasource_vectors(datasource_id)
        return result
    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"删除元数据向量失败: {e}")
        raise HTTPException(status_code=500, detail=f"删除元数据向量失败: {str(e)}")


@router.post("/metadata/search", response_model=MetadataSearchResponse)
async def search_metadata_vectors(
    request: MetadataSearchRequest,
    user=Depends(GetCurrentUser)
):
    """搜索元数据向量（为text2sql提供支撑）"""
    try:
        from src.server.services.metadata_vectorize_service import MetadataVectorizeService
        
        result = await MetadataVectorizeService.search_metadata_vectors(
            query=request.query,
            datasource_ids=request.datasource_ids,
            limit=request.limit
        )
        return result
    except Exception as e:
        logger.exception(f"搜索元数据向量失败: {e}")
        raise HTTPException(status_code=500, detail=f"搜索元数据向量失败: {str(e)}")


@router.get("/{datasource_id}/metadata/vectorize/stats")
async def get_vectorize_stats(
    datasource_id: str,
    user=Depends(GetCurrentUser)
):
    """获取元数据向量统计信息"""
    try:
        datasource = DataSource.GetById(datasource_id)
        if not datasource:
            raise HTTPException(status_code=404, detail=f"未找到ID为 {datasource_id} 的数据源")
        
        from src.server.services.metadata_vectorize_service import MetadataVectorizeService
        
        result = MetadataVectorizeService.get_vectorize_stats(datasource_id)
        return result
    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"获取向量统计信息失败: {e}")
        raise HTTPException(status_code=500, detail=f"获取向量统计信息失败: {str(e)}")


# 新增业务领域相关API
@router.get("/{datasource_id}/metadata/business-domains")
async def get_business_domains(
    datasource_id: str,
    user=Depends(GetCurrentUser)
):
    """获取数据源的业务领域分布"""
    try:
        datasource = DataSource.GetById(datasource_id)
        if not datasource:
            raise HTTPException(status_code=404, detail=f"未找到ID为 {datasource_id} 的数据源")
        
        from src.rag.metadata_milvus import MetadataVectorStore
        
        vector_store = MetadataVectorStore()
        stats = vector_store.get_stats(datasource_id)
        
        return {
            "success": True,
            "datasource_id": datasource_id,
            "domain_distribution": stats.get("domain_distribution", {}),
            "total_tables": stats.get("table_count", 0),
            "message": "获取业务领域分布成功"
        }
    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"获取业务领域分布失败: {e}")
        raise HTTPException(status_code=500, detail=f"获取业务领域分布失败: {str(e)}")


@router.get("/{datasource_id}/metadata/tables/{table_name}/relationships")
async def get_table_relationships(
    datasource_id: str,
    table_name: str,
    user=Depends(GetCurrentUser)
):
    """获取指定表的关联关系"""
    try:
        datasource = DataSource.GetById(datasource_id)
        if not datasource:
            raise HTTPException(status_code=404, detail=f"未找到ID为 {datasource_id} 的数据源")
        
        from src.rag.metadata_milvus import MetadataVectorStore
        
        vector_store = MetadataVectorStore()
        related_tables = vector_store.get_related_tables(table_name, datasource_id)
        
        return {
            "success": True,
            "table_name": table_name,
            "related_tables": related_tables,
            "count": len(related_tables),
            "message": f"找到 {len(related_tables)} 个关联表"
        }
    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"获取表关系失败: {e}")
        raise HTTPException(status_code=500, detail=f"获取表关系失败: {str(e)}")




# 表级搜索API
@router.get("/{datasource_id}/metadata/tables/search")
async def search_tables_by_name(
    datasource_id: str,
    table_name: str = Query(..., description="表名（支持模糊匹配）"),
    user=Depends(GetCurrentUser)
):
    """根据表名搜索表信息"""
    try:
        datasource = DataSource.GetById(datasource_id)
        if not datasource:
            raise HTTPException(status_code=404, detail=f"未找到ID为 {datasource_id} 的数据源")
        
        from src.rag.metadata_milvus import MetadataVectorStore
        
        vector_store = MetadataVectorStore()
        
        # 尝试精确匹配
        exact_result = vector_store.search_by_table_name(table_name, datasource_id)
        
        results = []
        if exact_result:
            results.append(exact_result)
        else:
            # 模糊搜索
            fuzzy_results = vector_store.search_metadata(
                query=f"table {table_name}",
                datasource_ids=[datasource_id],
                limit=5
            )
            results.extend(fuzzy_results)
        
        return {
            "success": True,
            "query": table_name,
            "results": results,
            "count": len(results),
            "message": f"找到 {len(results)} 个匹配的表"
        }
    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"搜索表失败: {e}")
        raise HTTPException(status_code=500, detail=f"搜索表失败: {str(e)}")


# 业务领域搜索API
@router.post("/metadata/search-by-domain")
async def search_by_business_domain(
    domain: str = Body(..., description="业务领域"),
    datasource_ids: Optional[List[str]] = Body(None, description="数据源ID列表"),
    limit: int = Body(10, description="返回结果数量"),
    user=Depends(GetCurrentUser)
):
    """按业务领域搜索元数据"""
    try:
        from src.rag.metadata_milvus import MetadataVectorStore
        
        vector_store = MetadataVectorStore()
        results = vector_store.search_by_business_domain(domain, datasource_ids, limit)
        
        return {
            "success": True,
            "domain": domain,
            "results": results,
            "count": len(results),
            "message": f"在业务领域 '{domain}' 中找到 {len(results)} 个结果"
        }
    except Exception as e:
        logger.exception(f"按业务领域搜索失败: {e}")
        raise HTTPException(status_code=500, detail=f"按业务领域搜索失败: {str(e)}")